using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using community.Models;
using System.Security.Cryptography;
using community.Data;
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authorization;

namespace community.Controllers
{
    /// <summary>
    /// 用户登录请求模型
    /// </summary>
    public class LoginDTO
    {
        /// <summary>
        /// 用户名
        /// </summary>
        [Required(ErrorMessage = "用户名不能为空")]
        public string Username { get; set; }

        /// <summary>
        /// 密码
        /// </summary>
        [Required(ErrorMessage = "密码不能为空")]
        public string Password { get; set; }

        /// <summary>
        /// 角色
        /// </summary>
        [Required(ErrorMessage = "角色不能为空")]
        public string Role { get; set; }
    }

    /// <summary>
    /// 修改密码请求模型
    /// </summary>
    public class ChangePasswordDTO
    {
        /// <summary>
        /// 原密码
        /// </summary>
        [Required(ErrorMessage = "原密码不能为空")]
        public string OldPassword { get; set; }

        /// <summary>
        /// 新密码
        /// </summary>
        [Required(ErrorMessage = "新密码不能为空")]
        [StringLength(100, MinimumLength = 6, ErrorMessage = "密码长度必须在6-100个字符之间")]
        public string NewPassword { get; set; }
    }

    /// <summary>
    /// 用户认证和权限管理接口
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    public class AuthController : ControllerBase
    {
        private readonly ApplicationDbContext _context;
        private readonly IConfiguration _configuration;

        public AuthController(ApplicationDbContext context, IConfiguration configuration)
        {
            _context = context;
            _configuration = configuration;
        }

        /// <summary>
        /// 管理员登录
        /// </summary>
        /// <param name="dto">登录信息</param>
        /// <returns>登录结果和JWT令牌</returns>
        /// <response code="200">登录成功</response>
        /// <response code="400">登录失败</response>
        [HttpPost("login")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        public async Task<IActionResult> Login(LoginDTO dto)
        {
            if (dto.Role != "Admin")
            {
                return BadRequest("此接口仅支持管理员登录");
            }

            var user = await _context.Users
                .FirstOrDefaultAsync(u => u.Username == dto.Username);

            if (user == null || !VerifyPassword(dto.Password, user.Password))
                return BadRequest("用户名或密码错误");

            if (user.Role != "Admin")
                return BadRequest("此账号不是管理员账号");

            var token = GenerateJwtToken(user);

            return Ok(new
            {
                Token = token,
                User = new
                {
                    user.Id,
                    user.Username,
                    user.FullName,
                    user.Email,
                    user.Role
                }
            });
        }

        /// <summary>
        /// 居民登录
        /// </summary>
        /// <param name="dto">登录信息</param>
        /// <returns>登录结果和JWT令牌</returns>
        /// <response code="200">登录成功</response>
        /// <response code="400">登录失败</response>
        [HttpPost("resident-login")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        public async Task<IActionResult> ResidentLogin(LoginDTO dto)
        {
            if (dto.Role != "Resident")
            {
                return BadRequest("此接口仅支持居民登录");
            }

            var resident = await _context.Residents
                .FirstOrDefaultAsync(r => r.Name == dto.Username);

            if (resident == null || !VerifyPassword(dto.Password, resident.Password))
                return BadRequest("用户名或密码错误");

            var token = GenerateJwtToken(new User
            {
                Id = resident.Id,
                Username = resident.Name,
                Role = "Resident"
            });

            return Ok(new
            {
                Token = token,
                User = new
                {
                    resident.Id,
                    Username = resident.Name,
                    FullName = resident.Name,
                    Email = resident.Phone, // 使用手机号作为邮箱
                    Role = "Resident"
                }
            });
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="dto">密码修改信息</param>
        /// <returns>修改结果</returns>
        /// <response code="200">密码修改成功</response>
        /// <response code="400">密码修改失败</response>
        /// <response code="401">未授权</response>
        [HttpPost("change-password")]
        [Authorize]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        public async Task<IActionResult> ChangePassword([FromBody] ChangePasswordDTO model)
        {
            // 获取当前用户ID并转换为int
            var userIdStr = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
            if (string.IsNullOrEmpty(userIdStr) || !int.TryParse(userIdStr, out int userId))
            {
                return Unauthorized();
            }

            var role = User.FindFirst(ClaimTypes.Role)?.Value;
            if (role == "Admin")
            {
                var user = await _context.Users.FindAsync(userId);
                if (user == null)
                    return NotFound("用户不存在");

                if (!VerifyPassword(model.OldPassword, user.Password))
                    return BadRequest("原密码错误");

                user.Password = HashPassword(model.NewPassword);
                await _context.SaveChangesAsync();
            }
            else if (role == "Resident")
            {
                // 调用居民修改密码接口
                var resident = await _context.Residents.FindAsync(userId);
                if (resident == null)
                    return NotFound("居民不存在");

                if (!VerifyPassword(model.OldPassword, resident.Password))
                    return BadRequest("原密码错误");

                resident.Password = HashPassword(model.NewPassword);
                await _context.SaveChangesAsync();
            }
            else
            {
                return Unauthorized();
            }

            return Ok(new { message = "密码修改成功" });
        }

        /// <summary>
        /// 获取当前用户信息
        /// </summary>
        /// <returns>用户信息</returns>
        /// <response code="200">成功获取用户信息</response>
        /// <response code="401">未授权</response>
        [HttpGet("me")]
        [Authorize]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        public async Task<IActionResult> GetCurrentUser()
        {
            var userId = int.Parse(User.FindFirst(ClaimTypes.NameIdentifier)?.Value);
            var role = User.FindFirst(ClaimTypes.Role)?.Value;
            object user;

            if (role == "Admin")
            {
                user = await _context.Users.FindAsync(userId);
                if (user == null)
                    return NotFound();

                return Ok(new
                {
                    ((User)user).Id,
                    ((User)user).Username,
                    ((User)user).FullName,
                    ((User)user).Email,
                    ((User)user).Role
                });
            }
            else if (role == "Resident")
            {
                user = await _context.Residents.FindAsync(userId);
                if (user == null)
                    return NotFound();

                return Ok(new
                {
                    ((Resident)user).Id,
                    Username = ((Resident)user).Name,
                    FullName = ((Resident)user).Name,
                    Email = ((Resident)user).Phone,
                    Role = "Resident"
                });
            }
            else
            {
                return Unauthorized();
            }
        }

        // 私有辅助方法
        private string HashPassword(string password)
        {
            using (var sha256 = SHA256.Create())
            {
                var hashedBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(password));
                return Convert.ToBase64String(hashedBytes);
            }
        }

        private bool VerifyPassword(string password, string hashedPassword)
        {
            return HashPassword(password) == hashedPassword;
        }

        private string GenerateJwtToken(User user)
        {
            var claims = new[]
            {
                new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                new Claim(ClaimTypes.Name, user.Username),
                new Claim(ClaimTypes.Role, user.Role)
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
            var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var expires = DateTime.Now.AddDays(Convert.ToDouble(_configuration["Jwt:ExpireDays"]));

            var token = new JwtSecurityToken(
                issuer: _configuration["Jwt:Issuer"],
                audience: _configuration["Jwt:Audience"],
                claims: claims,
                expires: expires,
                signingCredentials: credentials
            );

            return new JwtSecurityTokenHandler().WriteToken(token);
        }
    }
} 